package com.allwees.bs.module.mms.service.impl;

import com.allwees.bs.module.mms.entity.RetailerApply;
import com.allwees.bs.module.mms.service.RetailerApplyService;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.security.security.vo.JwtUser;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.DeptSmallDto;
import me.zhengjie.modules.system.service.dto.JobSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.StringUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author Zheng Jie
 * @date 2018-11-22
 */
@Service("userDetailsService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private RetailerApplyService retailerApplyService;

    @Override
    public UserDetails loadUserByUsername(String username){
        UserDto user = userService.findByName(username);

        boolean registered = true;
        if (user == null) {
            registered = false;
            RetailerApply apply = retailerApplyService.findOneByField("email", username);
            if (apply == null) {
                throw new BadRequestException("账号不存在");
            }
            user = toUserDto(apply);
            user.setShopCreated(StringUtils.isNotBlank(apply.getStoreName()));
        }
        user.setRegistered(registered);

        if (!user.isEnabled()) {
            throw new BadRequestException("账号未激活");
        }
        return createJwtUser(user);
    }

    private UserDto toUserDto(RetailerApply retailerApply){
        UserDto user = new UserDto();
        user.setUuid(retailerApply.getUuid());
        user.setEmail(retailerApply.getEmail());
        user.setUsername(retailerApply.getEmail());
        user.setPhone(retailerApply.getMobile());
        user.setPassword(retailerApply.getPassword());
        user.setEnabled(true);
        return user;
    }

    private UserDetails createJwtUser(UserDto user) {
        return new JwtUser(
                user.getId(),
                user.getUuid(),
                user.getUsername(),
                user.getNickName(),
                user.getSex(),
                user.getPassword(),
                user.getAvatar(),
                user.getEmail(),
                user.getPhone(),
                Optional.ofNullable(user.getDept()).map(DeptSmallDto::getName).orElse(null),
                Optional.ofNullable(user.getJob()).map(JobSmallDto::getName).orElse(null),
                roleService.mapToGrantedAuthorities(user),
                user.getEnabled(),
                user.getCreateTime(),
                user.getRoleNames(),
                user.getLastPasswordResetTime(),
                user.getBranchType(),
                user.getBranchUuid(),
                user.getStoreUuid(),
                user.getRegistered(),
                user.getShopCreated()
        );
    }
}
